// use g++ -mavx2 -mavx512f -mavx512dq avx2.cpp

#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <functional>

#include "define.hpp"

using namespace std;

#define COUNT (8)
#define WIDE (sizeof (__m256i) / sizeof (int))
#define N (WIDE * COUNT)

unsigned int a[N], b[N], c[N];
unsigned *res;

void print(const unsigned int &x)
{
  printf ("%u\t", x);
}

int main()
{
  printf ("%ld\n", sizeof (__m256i));
  printf ("%ld\n", sizeof (int));
  __m256i mask = _mm256_set_epi32 (0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
  __m256i ia, ib, ic;
  res = (unsigned int*)&mask;
  for_each (res, res + WIDE, print);
  puts("--");
  for (int i = 0; i < N; i++)
  {
    a[i] = i, b[i] = i;
  }
  for (int i = 0; i < COUNT; i++)
  {
    // ic[i] = _mm256_mullo_epi32 (ia[i], ib[i]);
    ia = _mm256_maskload_epi32 ((const int *)&a[WIDE * i], mask);
    ib = _mm256_maskload_epi32 ((const int *)&b[WIDE * i], mask);
    
    ic = _mm256_add_epi32 (_mm256_mullo_epi32 (ia, ib), ia);

    res = (unsigned int*)&ic;
    for_each (res, res + WIDE, print);
    puts("--");
    _mm256_maskstore_epi32 ((int *)&c[i * WIDE], mask, ic);
  }

  for_each (c, c + N, print);
  puts ("");
  return 0;
}